const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt'); //  加密数字的模块
const redis = require('redis');

const db = require('../config/database');//MySQL数据库连接
const redisClient =db.redisClient;       //获取redis客户端

const router = express.Router();

// Redis连接初始化
/*
(async () => {
  try {
    await redisClient.connect();
    console.log('Redis连接成功');
  } catch (err) {
    console.error('Redis连接失败:', err);
  }
})();

// Redis错误处理
redisClient.on('error', (err) => {
  console.error('Redis错误:', err);
});

// Redis重连机制
redisClient.on('reconnecting', () => {
  console.log('Redis正在重连...');
});

redisClient.on('ready', () => {
  console.log('Redis准备就绪');
});
*/

// 用户登录尝试次数限制
const MAX_LOGIN_ATTEMPTS = 10;
// 登录尝试窗口（单位：秒）
const LOGIN_ATTEMPT_WINDOW = 60 * 60; // 1小时

// 密码强度验证规则
const PASSWORD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}/;

// 用户注册
router.post('/register', async (req, res) => {
  const { username, email, password ,role} = req.body;

  // 验证必填字段
  if (!username || !email || !password ||!role) {
    return res.status(400).json({ code: -1, msg: '用户名、邮箱、角色和密码不能为空', data: {} });
  }

  // 验证用户名格式（2-50个字符，允许中文、字母、数字和下划线）
  if (!/^[\u4e00-\u9fa5a-zA-Z0-9_]{2,50}$/.test(username)) {
    return res.status(400).json({ code: -1, msg: '用户名格式不正确（2-50个字符，允许中文、字母、数字和下划线）', data: {} });
  }

  // 验证邮箱格式
  if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) {
    return res.status(400).json({ code: -1, msg: '邮箱格式不正确', data: {} });
  }

  // 验证密码强度
  if (!PASSWORD_REGEX.test(password)) {
    return res.status(400).json({ code: -1, msg: '密码必须包含大小写字母和数字，且长度至少8位', data: {} });
  }

  try {
    // 检查用户名是否已存在
    const [existingUsernames] = await db.pool.query(
      'SELECT id FROM users WHERE username = ?',
      [username]
    );

    if (existingUsernames.length > 0) {
      return res.status(400).json({ code: -1, msg: '该用户名已被使用', data: {} });
    }

    // 检查邮箱是否已存在
    const [existingEmails] = await db.pool.query(
      'SELECT id FROM users WHERE email = ?',
      [email]
    );

    if (existingEmails.length > 0) {
      return res.status(400).json({ code: -1, msg: '该邮箱已被注册', data: {} });
    }

    const hashedPassword = await bcrypt.hash(password, 10);
    
    // 将用户信息保存到数据库
    const [result] = await db.pool.query(
      'INSERT INTO users (username, email, password, role,created_at) VALUES (?, ?, ?,?, NOW())',
      [username, email, hashedPassword,role]
    );

    res.status(201).json({ 
      code: 0, 
      msg: '注册/添加成功', 
      data: {
        id: result.insertId,
        username,
        email,
        role: 'user'
      }
    });
  } catch (error) {
    res.status(500).json({ code: -1, msg: '注册失败', data: {} });
  }
});

// 用户登录
router.post('/login', async (req, res) => {
  const { email, password } = req.body;
  console.log("登录信息：",email,password);

  if (!email || !password) {
    return res.status(400).json({ code: -1, msg: '邮箱和密码不能为空', data: {} });
  }

  // 检查登录尝试次数
  const attempts = await redisClient.get(`login_attempts:${email}`);
  if (attempts >= MAX_LOGIN_ATTEMPTS) {
    return res.status(429).json({ code: -1, msg: '登录尝试次数过多，请稍后再试', data: {} });
  }

  try {
    // 从数据库获取用户信息
    const [users] = await db.pool.query(
      'SELECT * FROM users WHERE email = ?',
      [email]
    );

    console.log("用户信息：",users);

    if (users.length === 0) {
      // 当你的邮箱或密码错误的时候，在这里把email存到redis数据库，作为当前邮箱的请求登录次数，在上面登录尝试次数中起到关键作用
      await redisClient.incr(`login_attempts:${email}`); 
      return res.status(401).json({ code: -1, msg: '邮箱或密码错误', data: {} });
    }

    const user = users[0];
    const passwordMatch = await bcrypt.compare(password, user.password);
    console.log("密码匹配：",passwordMatch);

    // 密码不匹配，增加尝试次数并返回错误提示
    // 密码验证失败
    if (!passwordMatch) {
      await redisClient.incr(`login_attempts:${email}`);
      return res.status(401).json({ code: -1, msg: '密码错误，请重试', data: {} });
    }

    // 用户信息
    const userInfo = {
      id: user.id,
      username: user.username,
      email: user.email,
      role: user.role
    };
    // 生成 JWT
    const token = jwt.sign(
      userInfo,
      process.env.ACCESS_TOKEN_SECRET,
      { expiresIn: '1h' } // 1小时后过期
    );
    res.json({ code: 0, msg: '登录成功', data: { token,userInfo } });
  } catch (error) {
    console.error("登录异常：",error);
    res.status(500).json({ code: -1, msg: '登录失败', data: {} });
  }

  // 登录成功时清除尝试次数
  await redisClient.del(`login_attempts:${email}`);
});

// 用户登出
router.post('/logout', async (req, res) => {
  try {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
      return res.status(400).json({ code: -1, msg: '未提供token', data: {} });
    }

    try {
      // 验证token是否有效
      const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
      // 将token加入黑名单，过期时间与token的过期时间一致
      const tokenExp = decoded.exp;
      const now = Math.floor(Date.now() / 1000);
      const ttl = tokenExp - now;

      if (ttl > 0) {
        // 将token加入Redis黑名单
        await redisClient.setEx(`blacklist:${token}`, ttl, 'true');
      }

      res.json({ code: 0, msg: '登出成功', data: {} });
    } catch (err) {
      // token已过期或无效
      res.json({ code: 0, msg: '登出成功', data: {} });
    }
  } catch (error) {
    console.error('登出失败:', error);
    res.status(500).json({ code: -1, msg: '登出失败', data: {} });
  }
});

// 检查token状态
router.post('/check-token', async (req, res) => {
  try {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
      return res.status(401).json({ code: -1, msg: 'token不存在', data: {} });
    }

    // 检查token是否在黑名单中
    const isBlacklisted = await redisClient.get(`blacklist:${token}`);
    if (isBlacklisted) {
      return res.status(401).json({ code: -1, msg: 'token已失效', data: {} });
    }

    // 验证token
    const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
    res.json({ code: 0, msg: 'token有效', data: { userInfo: decoded } });
  } catch (error) {
    if (error instanceof jwt.TokenExpiredError) {
      return res.status(401).json({ code: -1, msg: 'token已过期', data: {} });
    }
    if (error instanceof jwt.JsonWebTokenError) {
      return res.status(401).json({ code: -1, msg: 'token无效', data: {} });
    }
    console.error('验证token失败:', error);
    res.status(500).json({ code: -1, msg: '服务器错误', data: {} });
  }
});

// 刷新token
router.post('/refresh-token', async (req, res) => {
  const refreshToken = req.body.refreshToken;

  // if (!refreshToken) {
  //   return res.status(401).json({ code:-1,msg: '未提供refreshToken' });
  // }

  const token = req.headers['authorization']?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ code: -1, msg: 'token不存在', data: {} });
  }

  try {
    // 验证refreshToken
    const decoded = jwt.verify(token, process.env.REFRESH_TOKEN_SECRET); // 替换为你的refreshToken密钥
    const userId = decoded.userId;

    // 生成新的accessToken
    const accessToken = jwt.sign({ userId }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '1h' });

    res.json({ code:0,msg:"刷新成功",data:{accessToken} });  // 返回新的accessToken
  }catch (error) {
    console.error('刷新token失败:', error);
    res.status(403).json({ code:-1,msg: '无效的refreshToken' });
  }
})

// JWT 验证中间件
const authMiddleware = async (req, res, next) => {
  const authHeader = req.headers['authorization'];
  // console.log("用户的token：：",req.headers)
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) return res.status(401).json({ code:-1,msg: '未授权访问',data:{} });

  try {
    // 检查token是否在黑名单中
    const isBlacklisted = await redisClient.get(`blacklist:${token}`);
    if (isBlacklisted) {
      return res.status(401).json({ code:-1,msg: 'token已失效，请重新登录',data:{}  });
    }

    jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
      if (err) return res.status(403).json({ code:-1,msg: '无效的token',data:{} });
      req.user = user;
      next();
    });
  } catch (error) {
    console.error('验证token失败:', error);
    return res.status(500).json({ code:-1,msg: '服务器错误',data:{} });
  }
};

// 管理员权限验证中间件
const adminMiddleware = (req, res, next) => {
  console.log("当前用户的身份",req.user.role)
  if (req.user.role !== 'admin' && req.user.role !== 'super_admin') {
    return res.status(403).json({ msg: '需要管理员权限',code:-1,data:{} });
  }
  next();
};

// 超级管理员权限验证中间件
const superAdminMiddleware = (req, res, next) => {
  console.log("当前用户的身份",req.user.role)
  if (req.user.role !== 'super_admin') {
    return res.status(403).json({ msg: '需要超级管理员权限',code:-1,data:{} });
  }
  next();
};

// 采用短期token结合静默刷新机制，在token过期前自动刷新，同时通过路由守卫进行主动验证。在关键用户操作时调用/check-token接口验证状态，配合axios拦截器处理401错误，避免频繁轮询。
module.exports = router;
module.exports.authMiddleware = authMiddleware;
module.exports.adminMiddleware = adminMiddleware;
module.exports.superAdminMiddleware = superAdminMiddleware;